﻿
using Consul;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Ccteg.Common
{
    public static class ConsulBuilderExtensions
    {
        public static ConsulServiceSettings _ConsulServiceSettings;
        //public ConsulBuilderExtensions(IOptionsMonitor<ConsulServiceSettings> appSettings)
        //{
        //    _appSettings = appSettings.CurrentValue; //IOptions 需要每次重新启动项目加载配置，IOptionsMonitor 每次更改配置都会重新加载，不需要重新启动项目。
        //}

        //  https://www.jianshu.com/p/4aaaee6e9ce1
        public static IApplicationBuilder RegisterConsul(this IApplicationBuilder app, IApplicationLifetime lifetime, ConsulServiceSettings serviceEntity)
        {
            _ConsulServiceSettings = serviceEntity;
            using (var consulClient = new ConsulClient(x => x.Address = new Uri($"{serviceEntity.ConsulScheme}://{serviceEntity.ConsulIP}:{serviceEntity.ConsulPort}")))//请求注册的 Consul 地址
            {

                var httpCheck = new AgentServiceCheck()
                {
                    DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服务启动多久后注册
                    Interval = TimeSpan.FromSeconds(10),//健康检查时间间隔，或者称为心跳间隔
                    HTTP = $"{serviceEntity.ServiceScheme}://{serviceEntity.ServiceIP}:{serviceEntity.ServicePort}/{serviceEntity.ServiceHealthCheck}",//健康检查地址
                    Timeout = TimeSpan.FromSeconds(5)
                };

                // Register service with consul
                var registration = new AgentServiceRegistration()
                {
                    Checks = new[] { httpCheck },
                    ID = serviceEntity.ServiceId,//Guid.NewGuid().ToString(),
                    Name = serviceEntity.ServiceName,// 服务名
                    Address = serviceEntity.ServiceIP,//// 服务绑定IP
                    Port = serviceEntity.ServicePort,// 服务绑定端口
                    Tags = new[] { $"urlprefix-/{serviceEntity.ServiceName+","+serviceEntity.ServiceId}" }//添加 urlprefix-/servicename 格式的 tag 标签，以便 Fabio 识别
                };

                consulClient.Agent.ServiceRegister(registration).Wait();//服务启动时注册，内部实现其实就是使用 Consul API 进行注册（HttpClient发起）
                lifetime.ApplicationStopping.Register(() =>
                {
                    consulClient.Agent.ServiceDeregister(registration.ID).Wait();//服务停止时取消注册
                });

                return app;
            }
        }

        public static ConsulClient GetConsulClient()
        {
            var consulClient = new ConsulClient(x => x.Address = new Uri($"{_ConsulServiceSettings.ConsulScheme}://{_ConsulServiceSettings.ConsulIP}:{_ConsulServiceSettings.ConsulPort}"));//请求注册的 Consul 地址
            return consulClient;
        }
    }
}
